home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2002 #11 / Amiga Plus CD - 2002 - No. 11.iso / Tools / Development / libogg / libvorbis-1.0rc3 / vq / lspdata.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-10-27  |  4.1 KB  |  158 lines

  1. /********************************************************************
  2.  *                                                                  *
  3.  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
  4.  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  5.  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  6.  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  7.  *                                                                  *
  8.  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
  9.  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
  10.  *                                                                  *
  11.  ********************************************************************
  12.  
  13.  function: metrics and quantization code for LSP VQ codebooks
  14.  last mod: $Id: lspdata.c,v 1.19 2001/12/20 01:00:39 segher Exp $
  15.  
  16.  ********************************************************************/
  17.  
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <stdio.h>
  21. #include "vqgen.h"
  22. #include "vqext.h"
  23. #include "codebook.h"
  24.  
  25. char *vqext_booktype="LSPdata";  
  26. quant_meta q={0,0,0,1};          /* set sequence data */
  27. int vqext_aux=1;
  28.  
  29. float global_maxdel=M_PI;
  30. float global_mindel=M_PI;
  31. #if 0
  32. void vqext_quantize(vqgen *v,quant_meta *q){
  33.   float delta,mindel;
  34.   float maxquant=((1<<q->quant)-1);
  35.   int j,k;
  36.  
  37.   /* first find the basic delta amount from the maximum span to be
  38.      encoded.  Loosen the delta slightly to allow for additional error
  39.      during sequence quantization */
  40.  
  41.   delta=(global_maxdel-global_mindel)/((1<<q->quant)-1.5f);
  42.   
  43.   q->min=_float32_pack(global_mindel);
  44.   q->delta=_float32_pack(delta);
  45.  
  46.   mindel=_float32_unpack(q->min);
  47.   delta=_float32_unpack(q->delta);
  48.  
  49.   for(j=0;j<v->entries;j++){
  50.     float last=0;
  51.     for(k=0;k<v->elements;k++){
  52.       float val=_now(v,j)[k];
  53.       float now=rint((val-last-mindel)/delta);
  54.       
  55.       _now(v,j)[k]=now;
  56.       if(now<0){
  57.     /* be paranoid; this should be impossible */
  58.     fprintf(stderr,"fault; quantized value<0\n");
  59.     exit(1);
  60.       }
  61.  
  62.       if(now>maxquant){
  63.     /* be paranoid; this should be impossible */
  64.     fprintf(stderr,"fault; quantized value>max\n");
  65.     exit(1);
  66.       }
  67.       last=(now*delta)+mindel+last;
  68.     }
  69.   }
  70.  
  71. }
  72. #else
  73. void vqext_quantize(vqgen *v,quant_meta *q){
  74.   vqgen_quantize(v,q);
  75. }
  76. #endif
  77.  
  78. float *weight=NULL;
  79. #if 0
  80. /* LSP training metric.  We weight error proportional to distance
  81.    *between* LSP vector values.  The idea of this metric is not to set
  82.    final cells, but get the midpoint spacing into a form conducive to
  83.    what we want, which is weighting toward preserving narrower
  84.    features. */
  85.  
  86. #define FUDGE (global_maxdel-weight[i])
  87.  
  88. float *vqext_weight(vqgen *v,float *p){
  89.   int i;
  90.   int el=v->elements;
  91.   float lastp=0.f;
  92.   for(i=0;i<el;i++){
  93.     float predist=(p[i]-lastp);
  94.     float postdist=(p[i+1]-p[i]);
  95.     weight[i]=(predist<postdist?predist:postdist);
  96.     lastp=p[i];
  97.   }
  98.   return p;
  99. }
  100. #else
  101. #define FUDGE 1.f
  102. float *vqext_weight(vqgen *v,float *p){
  103.   return p;
  104. }
  105. #endif
  106.  
  107.                             /* candidate,actual */
  108. float vqext_metric(vqgen *v,float *e, float *p){
  109.   int i;
  110.   int el=v->elements;
  111.   float acc=0.f;
  112.   for(i=0;i<el;i++){
  113.     float val=(p[i]-e[i])*FUDGE;
  114.     acc+=val*val;
  115.   }
  116.   return sqrt(acc/v->elements);
  117. }
  118.  
  119. /* Data files are line-vectors, now just deltas.  The codebook entries
  120.    want to be monotonically increasing, so we adjust */
  121.  
  122. /* assume vqext_aux==1 */
  123. void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){
  124.   float *a=alloca(sizeof(float)*(dim+1)); /* +aux */
  125.   float base=0;
  126.   int i;
  127.  
  128.   for(i=0;i<dim;i++)
  129.     base=a[i]=b[i+start]+base;
  130.  
  131.   if(start+dim+1>cols) /* +aux */
  132.     a[i]=M_PI;
  133.   else
  134.     a[i]=b[i+start]+base;
  135.   
  136.   vqgen_addpoint(v,a,a+dim);
  137. }
  138.  
  139. /* we just need to calc the global_maxdel from the training set */
  140. void vqext_preprocess(vqgen *v){
  141.   long j,k;
  142.  
  143.   global_maxdel=0.f;
  144.   global_mindel=M_PI;
  145.   for(j=0;j<v->points;j++){
  146.     float last=0.;
  147.     for(k=0;k<v->elements+v->aux;k++){
  148.       float p=_point(v,j)[k];
  149.       if(p-last>global_maxdel)global_maxdel=p-last;
  150.       if(p-last<global_mindel)global_mindel=p-last;
  151.       last=p;
  152.     }
  153.   }
  154.  
  155.   weight=_ogg_malloc(sizeof(float)*v->elements);
  156. }
  157.  
  158.